home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld 1998 September
/
Macworld (1998-09).dmg
/
Shareware World
/
Info
/
For Developers
/
MacZoop 1.8.3
/
Required Classes
/
Z Sources
/
ZPrinter.cpp
< prev
next >
Wrap
Text File
|
1998-06-11
|
8KB
|
378 lines
/*************************************************************************************************
*
*
* MacZoop - "the framework for the rest of us"
*
*
*
* ZPrinter.cpp -- an object for doing printing
*
*
*
*
*
* © 1996, Graham Cox
*
*
*
*
*************************************************************************************************/
#include "ZPrinter.h"
#include "ZWindow.h"
#include "MacZoop.h"
#include "ProjectSettings.h"
#if _PRINT_USING_PROGRESS_BAR
#include "ZProgress.h"
#endif
/*--------------------------------*** CONSTRUCTOR ***---------------------------------*/
ZPrinter::ZPrinter( ZWindow* aWindow )
{
printWindow = aWindow;
fakeWindow = NULL;
printInited = FALSE;
SetRect( &paperRect, 0, 0, 0, 0 );
// create a handle for the print record. This will be initialised to
// the default print settings when the user first chooses Page Setup or Print.
FailNIL( macPrintH = (THPrint) NewHandleClear( sizeof( TPrint )));
// set default print record and paper size
SetDefault();
paperRect = (*macPrintH)->prInfo.rPage;
}
/*---------------------------------*** DESTRUCTOR ***---------------------------------*/
ZPrinter::~ZPrinter()
{
if ( macPrintH )
DisposeHandle((Handle) macPrintH );
}
/*-----------------------------------*** PRINT ***------------------------------------*/
/*
print the contents of the current window
----------------------------------------------------------------------------------------*/
void ZPrinter::Print()
{
// verify that the window is valid and printable
FailOSErr((printWindow == NULL)? kBadWindowPrintRefErr : noErr );
FailOSErr( printWindow->IsPrintable()? noErr : kBadWindowPrintRefErr );
try
{
SetUpDocTitle( printWindow );
PrOpen();
FailOSErr( PrError());
PrintLoop();
PrClose();
if ( fakeWindow )
DisposeWindow( fakeWindow );
fakeWindow = NULL;
}
catch( OSErr err )
{
PrClose();
if ( fakeWindow )
DisposeWindow( fakeWindow );
fakeWindow = NULL;
throw err;
}
}
/*-----------------------------------*** PRINT ***------------------------------------*/
/*
print the contents of the window passed
----------------------------------------------------------------------------------------*/
void ZPrinter::Print( ZWindow* aWindow )
{
printWindow = aWindow;
Print();
}
/*-------------------------------*** GETPAPERRECT ***---------------------------------*/
/*
returns the paper rectangle. If not set up, this will be empty.
----------------------------------------------------------------------------------------*/
void ZPrinter::GetPaperRect( Rect* aRect )
{
*aRect= paperRect;
}
/*-----------------------------*** SETMACPRINTRECORD ***------------------------------*/
/*
allows existing print record to be set for the printer
----------------------------------------------------------------------------------------*/
void ZPrinter::SetMacPrintRecord( THPrint pRec )
{
if ( pRec == NULL )
PrintDefault( macPrintH );
else
{
if ( macPrintH )
DisposeHandle((Handle) macPrintH );
macPrintH = pRec;
printInited = TRUE;
paperRect = (*macPrintH)->prInfo.rPage;
}
}
/*---------------------------------*** PAGESETUP ***----------------------------------*/
/*
display the page setup dialog
----------------------------------------------------------------------------------------*/
void ZPrinter::PageSetUp()
{
// display the page setup dialog
try
{
PrOpen();
FailOSErr( PrError());
SetDefault();
StopCursorAnimation();
PrStlDialog( macPrintH );
PrClose();
paperRect = (*macPrintH)->prInfo.rPage;
}
catch( OSErr err )
{
PrClose();
// show the print problem alert, but do not propagate
Str15 errStr;
NumToString( err, errStr );
ParamText( errStr, NULL, NULL, NULL );
if (err != userCanceledErr)
(void) NotifyAlert( kInitPrinterAlertID );
}
}
/*---------------------------------*** PRINTLOOP ***-----------------------------------*/
/*
display the job dialog and print the range of pages selected
----------------------------------------------------------------------------------------*/
void ZPrinter::PrintLoop()
{
Boolean pgOpen = FALSE;
short copies;
// stick up the job dialog so the user can set copies, start, end, etc.
StopCursorAnimation();
if ( PrJobDialog( macPrintH ))
{
// user OK'd the dialog, so set the page ranges and start printing them.
// set up the paper rect. Note we set the static watch cursor since the print
// driver may do its own animation. We also do a quick window update here because
// the print dialog just went away leaving an update area, but no events are handled
// until the print job is complete.
printWindow->PerformUpdate();
SetCursorShape( watchCursor );
// OK, now do the real thing...
paperRect = (*macPrintH)->prInfo.rPage;
// calculate pagination. The window does this based on its content area and
// the paper area passed to it. Default pagination tiles first horizontally
// then vertically. pH and pV will be at least 1.
printWindow->CalcPages( paperRect, &pH, &pV );
pageStart = (*macPrintH)->prJob.iFstPage;
pageEnd = (*macPrintH)->prJob.iLstPage;
// make sure the end page is sensible to the actual number of pages
// to print.
if (pageEnd > (pH * pV))
pageEnd = (pH * pV);
if (pageStart < 1)
pageStart = 1;
// make the magic fix for mac happiness:
(*macPrintH)->prJob.iFstPage = 1;
(*macPrintH)->prJob.iLstPage = 9999;
// if using a progress bar, set it up:
#if _PRINT_USING_PROGRESS_BAR
short saveResFile = CurResFile();
UseResFile( gApplication->GetAppRefnum());
long max = pageEnd * (*macPrintH)->prJob.iCopies;
long pg = 1;
Str15 pgNum, totPg;
Str255 ppTitle;
ZProgress ppb( gApplication, kStdProgressResID, max, kNoButton );
NumToString( max, totPg );
GetWTitle( fakeWindow, ppTitle );
ppb.SetTitle( ppTitle );
ppb.SetMessage( 128, 12 );
UseResFile( saveResFile );
#endif
// print the requested number of copies
for( copies = 0; copies < (*macPrintH)->prJob.iCopies; copies++ )
{
// if page start is later than page end, nothing to print (sanity check)
if ( pageStart <= pageEnd )
{
printPort = PrOpenDoc( macPrintH, NULL, NULL );
FailOSErr( PrError());
try
{
printWindow->PrintingStarting();
// for each page, open the page and print it
for ( pageNum = pageStart; pageNum <= pageEnd; pageNum++ )
{
// if a progress bar, drive it
#if _PRINT_USING_PROGRESS_BAR
NumToString( pg, pgNum );
ParamText( pgNum, totPg, NULL, NULL );
if ( ! ppb.InformProgress( pg++ ))
FailOSErr( userCanceledErr );
#endif
PrOpenPage( printPort, NULL );
FailOSErr( PrError());
pgOpen = TRUE;
// call the window to do the relevant rendering, etc.
printWindow->PrintOnePage( pageNum, paperRect );
PrClosePage( printPort );
FailOSErr( PrError());
pgOpen = FALSE;
}
// the printing has finished, so inform the window
printWindow->PrintingFinishing();
}
catch( OSErr err )
{
if ( pgOpen )
PrClosePage( printPort );
PrCloseDoc( printPort );
throw err;
}
PrCloseDoc( printPort );
FailOSErr( PrError());
// we may need to spool the file, so check the spool flag
TPrStatus prStatus;
if ((*macPrintH)->prJob.bJDocLoop == bSpoolLoop )
{
PrPicFile( macPrintH, NULL, NULL, NULL, &prStatus);
FailOSErr( PrError());
}
}
}
}
}
void ZPrinter::SetUpDocTitle( ZWindow* aWindow )
{
// mac print driver assums top window is the one we are printing. This is not true if we
// have floaters, so to make sure, we create a temporary front window hidden behind the
// menubar and make sure its title is set to the doc we are printing.
Rect r = { 0, 0, 3, 3 };
Str31 title;
aWindow->GetName( title );
fakeWindow = NewWindow( NULL, &r, title, TRUE, 0, (WindowPtr) -1L, FALSE, 0);
SelectWindow( fakeWindow );
}
void ZPrinter::SetDefault()
{
if ( ! printInited )
{
PrOpen();
FailOSErr( PrError());
try
{
PrintDefault( macPrintH );
FailOSErr( PrError());
PrClose();
printInited = TRUE;
}
catch( OSErr err )
{
PrClose();
throw err;
}
}
}